package com.jkkc.lib.base.util.usb

import android.app.Application
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ThreadUtils
import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.driver.UsbSerialProber
import com.jkkc.lib.base.extend.ACTION_USB_PERMISSION
import com.jkkc.lib.base.extend.TIME_THREE_SECOND
import java.io.IOException
import java.lang.Exception

/**
 * Author:LiXian
 * <p>
 * Desc:USB发令枪辅助类
 * Version:1.0
 * date 2023/2/13 10:18
 */
object UsbManager {

    private var mUsbReceiver: UsbStateReceiver? = null
    private var mContext: Application? = null

    fun initUsbHelper(mContext: Application, iUsbChangedListener: IUsbChangedListener) {
        if (this.mContext == null) {
            this.mContext = mContext
        }
        //注册USB插拔广播
        if (mUsbReceiver == null) {
            val filter = IntentFilter()
            mUsbReceiver = UsbStateReceiver(iUsbChangedListener)
            filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
            filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
            filter.addAction(ACTION_USB_PERMISSION)
            mContext.registerReceiver(mUsbReceiver, filter)
        }

        //申请USB权限（APP未启动，就已经插入了USB设备，直接申请USB权限）
        ThreadUtils.runOnUiThreadDelayed({
            val manager = mContext.getSystemService(Context.USB_SERVICE)
            if (manager is UsbManager) {
                val mDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
                if (!mDrivers.isNullOrEmpty()) {
                    manager.requestPermission(mDrivers[0].device, getPendingIntent())
                }
            }
        }, TIME_THREE_SECOND)
    }

    private fun getPendingIntent(): PendingIntent? {
        if (mContext != null) {
            return PendingIntent.getBroadcast(mContext!!, 0, Intent(ACTION_USB_PERMISSION), 0)
        }
        return null
    }

    fun cancel() {
        try {
            mUsbReceiver?.let { mContext?.unregisterReceiver(it) }
            mUsbReceiver = null
            mContext = null
        } catch (e: Exception) {
            LogUtils.d("反注册广播异常 e = $e")
        }
    }

    /**
     * 申请USB权限
     *
     * @param usbDevice 需要申请权限的USB设备
     */
    fun applyUsbPermission(usbDevice: UsbDevice) {
        mContext?.let {
            val pendingIntent = PendingIntent.getBroadcast(it, 0, Intent(ACTION_USB_PERMISSION), 0)
            val manager = it.getSystemService(Context.USB_SERVICE)
            if (manager is UsbManager) {
                // 该代码执行后，系统弹出一个对话框/等待权限
                manager.requestPermission(usbDevice, pendingIntent)
            } else {
                LogUtils.d("系统不支持USB管理")
            }
        }
    }

    /**
     * 连接USB串口通信
     *
     * @param usbDevice 需要连接的USB设备
     * @param baudRate 波特率
     * @param dataBits 数据位数
     */
    fun connectionUsbSerialPort(usbDevice: UsbDevice, baudRate: Int, dataBits: Int): UsbSerialPortImpl? {
        mContext?.let {
            val manager = it.getSystemService(Context.USB_SERVICE)
            if (manager is UsbManager) {
                val connection: UsbDeviceConnection = manager.openDevice(usbDevice) ?: return null
                val driver = UsbSerialProber.getDefaultProber().probeDevice(usbDevice)
                if (driver == null || driver.ports.isEmpty()) return null
                val serialPort: UsbSerialPort = driver.ports[0]
                return try {
                    serialPort.open(connection)
                    serialPort.setParameters(baudRate, dataBits, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
                    LogUtils.i("获取到USB设备 test===", "device=" + serialPort.device.vendorId + ";ProductId=" + serialPort.device.productId)
                    UsbSerialPortImpl(serialPort)
                } catch (e: IOException) {
                    e.printStackTrace()
                    null
                }
            }
        }
        return null
    }
}